<script setup>
import {reactive, onBeforeMount, computed } from 'vue'
import Swal from 'sweetalert2/dist/sweetalert2.js'
import 'sweetalert2/dist/sweetalert2.min.css'
//import '@sweetalert2/theme-material-ui/material-ui.min.css'
import ImageUpload from '@/components/ImageUpload.vue'
import catalogApi from '@/api/system/CatalogApi'
import fileApi from '@/api/system/FileApi'

const props = defineProps({
  modelValue: {type: [Object, String], default: null},
  limit: {type:Number, default: 8}
})
const emits = defineEmits(['update:modelValue', 'selected'])
const state = reactive({
  list: computed({
    get(){
      if(props.modelValue instanceof Array){
        return props.modelValue
      }else {
        if(props.modelValue==undefined||props.modelValue==''){
          return []
        }else{
          return [ props.modelValue ]
        }
      }
    },
    set(val){
      if(props.modelValue instanceof Array){
        emits('update:modelValue', val)
      }else {
        if(val.length == 0){
          emits('update:modelValue', '')
        }else{
          emits('update:modelValue', val[0])
        }
      }
    }
  }),
  selectLimit: computed({
    get(){
      return (props.modelValue instanceof Array)? props.limit:1
    }
  }),
  visible: false,
  treeData: [],
  dataLoading: false,
  dataList: [],
  keyword: '',
  selectImgs: [],
  // 预览相关
  previewVisible: false,
  previewUrl: '',
  // 分类目录相关
  catalogVisible: false,
  catalogTitle: '编辑类型',
  catalogId: '',
})

//移去选中图片
const onRemoveImage =(idx)=>{
  state.list.splice(idx, 1)
  // 必须才能触发
  if(state.list.length==0) state.list =[]
}

// 查询参数
const queryParam = reactive({
  current :1,
  size: 12
})

// 搜索数据
const onSearchData =()=>{
  queryParam.current = 1
  fetchPageData()
}

// 改变每页大小
const onChangePage =(current, pageSize)=>{
  //console.log(current, pageSize)
  queryParam.current = current
  queryParam.size = pageSize
  fetchPageData()
}

// 查看图片
const onPreviewImage = (url)=>{
  state.previewUrl = url
  state.previewVisible = true
}
// 选择图片
const onSelectImage = img =>{
  if(state.selectImgs.some(item=> item.uuid== img.uuid)){
    img.selected = false
    state.selectImgs = state.selectImgs.filter(item=> item.uuid!= img.uuid)
  }else{
    img.selected = true
    state.selectImgs.push(img)
  }
}

// 删除单个图片
const onDeleteImage = img => {
  Swal.fire({
    icon: 'warning', // 弹框类型
    title: '删除图片', //标题
    text: '删除图片将无法恢复，请谨慎操作！', //显示内容            
    confirmButtonColor: '#3085d6',// 确定按钮的 颜色
    confirmButtonText: '确定',// 确定按钮的 文字
    showCancelButton: true, // 是否显示取消按钮
    cancelButtonColor: '#d33', // 取消按钮的 颜色
    cancelButtonText: '取消', // 取消按钮的 文字

    focusCancel: true, // 是否聚焦 取消按钮
    reverseButtons: true  // 是否 反转 两个按钮的位置 默认是  左边 确定  右边 取消
  }).then((isConfirm) => {
    //判断 是否 点击的 确定按钮
    if (isConfirm.value) {
      let ids =[img.id]
      // 
      fileApi.removeData({ids }).then(()=>{
        Swal.fire({
          showConfirmButton: false,
          timer: 3000,
          icon: 'success',
          title: '删除图片成功',
          willClose: ()=>{
            queryParam.current = 1
            fetchPageData()
          }
        })
      })
    }
  })
}

// 删除选择中图片
const onDeletedSelectedImage =() =>{
  Swal.fire({
    icon: 'warning', // 弹框类型
    title: '删除图片', //标题
    text: '删除图片将无法恢复，请谨慎操作！', //显示内容            
    confirmButtonColor: '#3085d6',// 确定按钮的 颜色
    confirmButtonText: '确定',// 确定按钮的 文字
    showCancelButton: true, // 是否显示取消按钮
    cancelButtonColor: '#d33', // 取消按钮的 颜色
    cancelButtonText: '取消', // 取消按钮的 文字

    focusCancel: true, // 是否聚焦 取消按钮
    reverseButtons: true  // 是否 反转 两个按钮的位置 默认是  左边 确定  右边 取消
  }).then((isConfirm) => {
    //判断 是否 点击的 确定按钮
    if (isConfirm.value) {
      let ids =state.selectImgs.map(item=> item.id )
      // 
      fileApi.removeData({ids }).then(()=>{
        state.selectImgs = []
        Swal.fire({
          showConfirmButton: false,
          timer: 3000,
          icon: 'success',
          title: '删除图片成功',
          willClose: ()=>{
            queryParam.current = 1
            fetchPageData()
          }
        })
      })
    }
  })
}

// 确认选择中图片
const onConfirmSelectedImage = () =>{
  let arrImgs =state.selectImgs.map(item=>{
    item.selected = false
    return item.url
  })
  state.list.push(...arrImgs)
  state.list = state.list.slice(0, state.selectLimit)
  emits('selected', arrImgs)
  state.visible = false
  state.selectImgs = []
}

// ===目录分类相关操作 ------------------------------------
// 目录表单
const formState = reactive({
  id: 0,
  pid: 0,
  name: ''
})
// 选中目录
const onSelected = (keys, e) =>{
  if(e.selected){
    state.catalogId = e.node.value
  }else{
    state.catalogId = ''
  }
  queryParam.current = 1
  fetchPageData()
  // console.log(e.selectedNodes)
  // console.log(e.node)
  // console.log(e.event)
  console.log(keys)
}
// 
const onEditCatalog =(node)=>{
  // console.log(node)
  state.catalogVisible = true
  state.catalogTitle = '修改目录'
  formState.id= node.value
  formState.name= node.label
  let pid = findParentById(state.treeData, node.value)
  //console.log('找到的PID是：：', pid)
  formState.pid= pid
}
//
const onDeleteCatalog =(node)=>{
  if(node.children !=undefined){
    Swal.fire('禁止删除', '该目录下有子目录不能删除', 'error')
  }else{
    Swal.fire({
      icon: 'warning', // 弹框类型
      title: '删除目录', //标题
      text: '删除目录将无法恢复，请谨慎操作！', //显示内容            
      confirmButtonColor: '#3085d6',// 确定按钮的 颜色
      confirmButtonText: '确定',// 确定按钮的 文字
      showCancelButton: true, // 是否显示取消按钮
      cancelButtonColor: '#d33', // 取消按钮的 颜色
      cancelButtonText: '取消', // 取消按钮的 文字

      focusCancel: true, // 是否聚焦 取消按钮
      reverseButtons: true  // 是否 反转 两个按钮的位置 默认是  左边 确定  右边 取消
    }).then((isConfirm) => {
      try {
        //判断 是否 点击的 确定按钮
        if (isConfirm.value) {
          let ids = [node.value]
          catalogApi.removeData({ids}).then(res=>{
            if(res.code){
              Swal.fire({
                toast: true,
                showConfirmButton: false,
                timer: 2000,
                icon: 'success',
                title: '删除目录成功',
                willClose: ()=>{
                  fetchCatalogData()
                }
              })
            }
          })
        }
      } catch (e) {
        alert(e)
      }
    })
  }
}
//
const onAddCatalog =(node)=>{
  state.catalogVisible = true
  state.catalogTitle = '增加子目录'

  formState.id= ''
  formState.name= ''
 
  formState.pid= node.value
}
// 提交单表
const onFinish =()=>{
  catalogApi.saveData(formState).then(res=>{
    if(res.code==0){
      Swal.fire({
        toast: true,
        showConfirmButton: false,
        timer: 2000,
        icon: 'success',
        title: '保存成功',
        didOpen: () => {
          state.catalogVisible = false
        }
      })
      // 成功刷新目录数据
      fetchCatalogData()
    }
  }) 
}
//
const onFinishFailed =()=>{
  console.log('表单验证失败的提示')
}

/**
 * 查找上一级ID
 */
function findParentById(arr,id){
  let parentId = '',
    hasParentId = function loop(arr){
      return arr.some((item)=>{
        if(item.value === id){
          return true
        }else if(Array.isArray(item.children)){
          parentId = item.value
          return loop(item.children)
        }else{
          return false
        }
      })
    }(arr)
  return hasParentId ? parentId : ''
}
// ===目录分类相关操作 ---------End---------------------------
// 获取分页数据
const fetchPageData=()=>{
  state.selectImgs =[]
  let params = {searchKey: state.keyword, catalogId: state.catalogId, pager: queryParam}
  state.dataLoading = true
  fileApi.getListByPage(params).then(res=>{
    if(res.code == 0){
      state.dataList = res.dataList
      queryParam.total =res.pagination.total
      queryParam.current =res.pagination.current
      queryParam.size =res.pagination.size
    }
  }).finally(()=>{
    state.dataLoading = false
  })
}

// 获取分类数据
const fetchCatalogData = ()=>{
  catalogApi.getTreeOptions('img').then(res=>{
    if(res.code == 0) {
      state.treeData =[]
      state.treeData.push(res.data)
    }
  })
}

const onChangeCatalog=(...args)=>{
  console.log(args)
}
// 加载时调用
onBeforeMount(()=>{
  fetchCatalogData()
  fetchPageData()
})
</script>
<template>
  <div class="image-wrapper">
    <div v-for="(img, idx) in state.list" :key="idx" class="up-card">
      <div class="up-thumb">
        <img class="thumb-img" :src="img">
        <div class="thumb-action">
          <div class="act-item" @click="onPreviewImage(img)"><eye-outlined /></div>
          <div class="act-item" @click="onRemoveImage(idx)"><delete-outlined /></div>
        </div>
      </div>
    </div>
    <button
      v-if="state.selectLimit > state.list.length"
      style="width: 60px; height: 60px; font-size: 36px; border: 1px solid #f0f0f0; border-radius: 5px; cursor: pointer;" 
      @click.prevent="state.visible = true">
      <picture-outlined />
    </button>
  </div>
  <!-- 主体 -->
  <a-modal v-model:visible="state.visible" title="选择图片" width="1000px" :footer="null">
    <a-row style="background-color: #fff;">
      <a-col :span="6">
        <!-- 分类目录 -->
        <a-tree
          :tree-data="state.treeData"
          default-expand-all
          @select="onSelected"
        >
          <template #title="{data}">
            <div class="tree-item-box">
              <span>  {{ data.label }} </span>
              <span>
                <a-dropdown>
                  <a class="ant-dropdown-link" @click.stop>
                    <more-outlined />
                  </a>
                  <template #overlay>
                    <a-menu>
                      <a-menu-item @click="onEditCatalog(data)">
                        <edit-outlined />修改
                      </a-menu-item>
                      <a-menu-item @click="onDeleteCatalog(data)">
                        <delete-outlined />删除
                      </a-menu-item>
                      <a-menu-item @click="onAddCatalog(data)">
                        <plus-outlined />增加
                      </a-menu-item>
                    </a-menu>
                  </template>
                </a-dropdown> 
              </span>
            </div>
          </template>
        </a-tree>
      </a-col>
      <a-col :span="18">
        <a-row>
          <a-col flex="500px">
            <a-button type="primary" :disabled="state.selectImgs.length ==0" @click="onConfirmSelectedImage">
              <template #icon><check-circle-outlined /></template>选中
            </a-button>
            <a-button type="primary" danger :disabled="state.selectImgs.length ==0" @click="onDeletedSelectedImage">
              <template #icon><delete-outlined /></template>删除
            </a-button>
            <image-upload @finish="fetchPageData" />
            <a-input-search
              v-model:value="state.keyword"
              placeholder="图片名"
              style="width: 210px"
              enter-button
              allow-clear
              @search="onSearchData"
            />
          </a-col>
          <a-col flex="auto" />
        </a-row>
        <a-row>
          <a-col :span="24">
            <!-- 图片列表 -->
            <a-list :grid="{ gutter: 5, column: 6 }" :data-source="state.dataList" :loading="state.dataLoading">
              <template #renderItem="{ item }">
                <a-list-item>
                  <div class="polaroid" :class="{'on': item.selected}">
                    <span class="number">{{ state.selectImgs.indexOf(item) +1 }}</span>
                    <a @click="onSelectImage(item)">
                      <img :alt="item.uuid" :src="item.url">
                    </a>
                    <ul class="actions">
                      <li><a @click="onPreviewImage(item.url)"><picture-outlined /></a></li>
                      <li>
                        <a-tooltip color="volcano">
                          <template #title>
                            <div>{{ item.original }}</div>
                            <div><sub>{{ item.uploadOn }}</sub></div>
                          </template>
                          <copyright-circle-outlined />
                        </a-tooltip>
                      </li>
                      <li>
                        <a @click="onDeleteImage(item)"><delete-outlined /></a>
                      </li>
                    </ul>
                  </div>
                </a-list-item>
              </template>
            </a-list>
            <!-- 分页-->
            <a-pagination
              v-model:current="queryParam.current"
              v-model:pageSize="queryParam.size"
              show-size-changer
              :page-size-options="['24', '36', '72']"
              :total="queryParam.total"
              @change="onChangePage"
            />
          </a-col>
        </a-row>
      </a-col>
    </a-row>
  </a-modal>
  <!-- 图片预览 -->
  <a-image
    :style="{ display: 'none' }"
    :preview="{ visible: state.previewVisible, onVisibleChange: (value)=>state.previewVisible = value }"
    :src="state.previewUrl" />
  <!-- 分类目录表单 -->
  <a-modal v-model:visible="state.catalogVisible" :title="state.catalogTitle" :footer="null">
    <a-form
      :model="formState"
      :label-col="{ span: 4 }"
      :wrapper-col="{ span: 16 }" 
      autocomplete="off"
      @finish="onFinish"
      @finish-failed="onFinishFailed"
    >
      <a-form-item
        label="上级目录"
        name="pid"
        :rules="[{ required: true, message: '请选择上级目录!' }]">
        <a-tree-select 
          v-model:value="formState.pid"
          :tree-data="state.treeData"
          tree-node-filter-prop="label"
          show-search
          tree-default-expand-all 
          allow-clear
          @change="onChangeCatalog" />
      </a-form-item>
      <a-form-item
        label="名称"
        name="name"
        :rules="[{ required: true, message: '请输入目录名称!' }]">
        <a-input v-model:value="formState.name" show-count :minlength="2" :maxlength="20" allow-clear />
      </a-form-item>
      <a-form-item :wrapper-col="{ offset: 8, span: 16 }">
        <a-button type="primary" html-type="submit">保存</a-button>
      </a-form-item>
    </a-form>
  </a-modal>
</template>
<style lang="less" scoped>
:deep(.ant-tree ) {
  .ant-tree-treenode, .ant-tree-node-content-wrapper {
    width: 100%;
  }
}
.tree-item-box {
  display: flex;
  justify-content:space-between;
}
.polaroid {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  overflow: hidden;
  position: relative;
  border: 1px solid rgb(230, 227, 227);
  margin: 12px 5px;
  width: 100px; height: 128px;
  img { width: 100%;max-width: 100px;max-height: 100px; border: 2px solid transparent;}
  .number {
    position: absolute; top: 3px;
    padding: 2px 10px;
    backdrop-filter: blur(3px);
    font-size: 12px; color: red;  font-weight: 900;
    box-shadow: 0 4px 8px 0 rgba(199, 146, 146, 0.2);
    border: 2px solid #fff;
    border-radius: 10px;
    transition: all 0.4s;
    transform: translateX(200px); 
  }
  ul {
    list-style: none;
    padding: 2px;
    display: flex;
    justify-content: space-between;
    margin: 0;
  }
  li {
    color: rgb(158, 160, 156);
    margin: 0px 2px; padding: 0px 2px;
  }
}
.polaroid.on {
  border: 1px solid transparent;
  box-shadow: 0 4px 8px 0 rgba(0,0,0, 0.2), 0 6px 20px 0 rgba(0,0,0, 0.19);
  .number {  transform: translateX(0); }
}

.image-wrapper{
    display: flex;
    flex-flow: row wrap;
    margin-bottom: -20px;
    .up-card {
      overflow: hidden;
      position: relative;
      border: 1px dashed rgb(233, 232, 232);
      padding: 0px;
      width: 60px;height: 60px;
      margin-right:5px; border-radius: 5px;
      background-color: #fbfaf7;
      transition: box-shadow 0.3s ease; /* 添加过渡效果 */
      .up-thumb {
        overflow: hidden;
        .thumb-img { 
          width: 100%; height: 100%; 
          /* object-fit: cover; 图片保持原有比例，不拉伸。*/ 
        }
        .thumb-action {
          position: absolute;
          left: 50%;
          transform: translateX(-50%);
          bottom: 10px;
          display: flex;
          align-items: center;
          
          .act-item {
            margin: 0 2px;
            background: rgba(255, 255, 255, 0.5);
            height: 35px; width: 35px;
            text-align: center; line-height: 31px;
            border: 2px solid #fff; cursor: pointer;
            transition: all 0.4s;
          }
          .act-item:nth-child(1) {transform: translateX(-200px); }
          .act-item:nth-child(2) {transform: translateX(200px); }
          .act-item:hover {background-color: #fff; border-radius: 50%; }
        }
      }
    }
    .up-card:hover {
      color: cadetblue;
      border: 1px dashed rgb(155, 154, 154);
      box-shadow: 0 0 10px rgba(0,0,0,0.5); /* 阴影效果*/
      .up-thumb{
        .thumb-action {
          .act-item {
            transform: translateX(0); }
        }
      }
    }
}
</style>